package com.wuhenzhizao.sku.use;

import android.content.Context;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.LinearLayout;


import com.wuhenzhizao.sku.bean.Sku;
import com.wuhenzhizao.sku.bean.SkuAttribute;
import com.wuhenzhizao.sku.utils.ViewUtils;
import com.wuhenzhizao.sku.view.OnSkuListener;
import com.wuhenzhizao.sku.view.SkuViewDelegate;
import com.wuhenzhizao.sku.widget.SkuMaxHeightScrollView;

import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * Created by wuhenzhizao on 2017/7/31.
 */
public class SkuSelectScrollView extends SkuMaxHeightScrollView implements SkuItemLayout.OnSkuItemSelectListener {
	private LinearLayout skuContainerLayout;
	private List<Sku> skuList;
	private List<SkuAttribute> selectedAttributeList;  // 存放当前属性选中信息，0存放{颜色 ，粉色} 1存放{尺寸：大}
	private OnSkuListener listener;                    // sku选中状态回调接口

	public SkuSelectScrollView(Context context) {
		super(context);
		init(context, null);
	}

	public SkuSelectScrollView(Context context, AttributeSet attrs) {
		super(context, attrs);
		init(context, attrs);
	}

	private void init(Context context, AttributeSet attrs) {
		setFillViewport(true);
		setOverScrollMode(OVER_SCROLL_NEVER);
		skuContainerLayout = new LinearLayout(context, attrs);
		skuContainerLayout.setId(ViewUtils.generateViewId());
		skuContainerLayout.setOrientation(LinearLayout.VERTICAL);
		skuContainerLayout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
		addView(skuContainerLayout);
	}

	/**
	 * 设置SkuView委托，MVVM + Databinding模式下使用
	 *
	 * @param delegate
	 */
	public void setSkuViewDelegate(SkuViewDelegate delegate) {
		this.listener = delegate.getListener();
	}

	/**
	 * 设置监听接口
	 *
	 * @param listener {@link OnSkuListener}
	 */
	public void setListener(OnSkuListener listener) {
		this.listener = listener;
	}

	/**
	 * 绑定sku数据
	 *
	 * @param skuList
	 */
	public void setSkuList(List<Sku> skuList) {
		this.skuList = skuList;
		// 清空sku视图
		skuContainerLayout.removeAllViews();

		// 获取分组的sku集合
		Map<String, List<String>> dataMap = getSkuGroupByName(skuList); // 获取规格组名称
		selectedAttributeList = new LinkedList<>();
		int index = 0;
		// ①后台返回的数据不止一条的时候
		for (Iterator<Map.Entry<String, List<String>>> it = dataMap.entrySet().iterator(); it.hasNext(); ) { //dataMap遍历
			Map.Entry<String, List<String>> entry = it.next();

			// 构建sku视图
			SkuItemLayout itemLayout = new SkuItemLayout(getContext()); // 创建规格item
			itemLayout.setId(ViewUtils.generateViewId());  // 设置id
			itemLayout.setLayoutParams(new LinearLayout.LayoutParams(
					LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT
			));
			itemLayout.buildItemLayout(index++, entry.getKey(), entry.getValue()); // 创建规格组布局
			itemLayout.setListener(this);  // 设置item的监听
			skuContainerLayout.addView(itemLayout); // 将这组规格加入到视图中
			// 初始状态下，所有属性信息设置为空
			selectedAttributeList.add(new SkuAttribute(entry.getKey(), ""));  // 添加规格组名称
		}
		// ②如果后台仅仅返回一条数据的时候
		if (skuList.size() == 1) {
			selectedAttributeList.clear();  // 清空
			for (SkuAttribute attribute : this.skuList.get(0).getAttributes()) {
				selectedAttributeList.add(new SkuAttribute(attribute.getKey(), attribute.getValue())); // 将 这个 的组名和规格设置到选中的list中
			}
		}
		// 清除所有选中状态，将所有的规格组下的所有的规格item的状态都转化为----不可点击 、 灰色
		clearAllLayoutStatus();
		// 设置规格item的状态是否可以点击，分为两种情况：单个的规格组   组合的多规格组
		optionLayoutEnableStatus();
		// 设置选中状态
		optionLayoutSelectStatus();
	}

	/**
	 * 将sku根据属性名进行分组
	 * 获取规格组的名称
	 *
	 * @param list
	 * @return 如{ "颜色": {"白色", "红色", "黑色"}, "尺寸": {"M", "L", "XL", "XXL"}}
	 */
	private Map<String, List<String>> getSkuGroupByName(List<Sku> list) {
		Map<String, List<String>> dataMap = new LinkedHashMap<>(); //
		for (Sku sku : list) {
			for (SkuAttribute attribute : sku.getAttributes()) {
				String attributeName = attribute.getKey();   // 获取规格所属的组名
				String attributeValue = attribute.getValue(); // 获取规格的名称
				if (!dataMap.containsKey(attributeName)) { // 如果有序的map中没有当前的组名
					dataMap.put(attributeName, new LinkedList<String>()); // 将当前的组名加入到有序的map中
				}
				List<String> valueList = dataMap.get(attributeName);  // 通过组名获取，存储在组名下的map中的此组名下的规格list
				if (!valueList.contains(attributeValue)) { // 判断下此list中是否含有 规格
					dataMap.get(attributeName).add(attributeValue);  // 如果没有，则将当前的规格加入到 map的list中去
				}
			}
		}
		return dataMap;
	}

	/**
	 * 重置规格组下的item的属性
	 */
	private void clearAllLayoutStatus() {
		for (int i = 0; i < skuContainerLayout.getChildCount(); i++) {   // 获取规格组的个数，现在是2个
			SkuItemLayout itemLayout = (SkuItemLayout) skuContainerLayout.getChildAt(i); // 循环遍历获取规格组,获取规格组对象
			itemLayout.clearItemViewStatus(); // 调用此对象的方法，将此规格组下的内容重置
		}
	}

	/**
	 * 设置所有属性的Enable状态，即是否可点击
	 * 分为：单规格组  多规格组
	 */
	private void optionLayoutEnableStatus() {
		int childCount = skuContainerLayout.getChildCount();  // 规格组的个数
		if (childCount <= 1) {  // 如果有0或者1个规格组，
			optionLayoutEnableStatusSingleProperty();
		} else { // 如果多于1个的规格组，设置规格item是否可以点击
			optionLayoutEnableStatusMultipleProperties();
		}
	}

	/**
	 * 一个规格组的情况下，查询规格item的库存，设置可点击
	 */
	private void optionLayoutEnableStatusSingleProperty() {
		SkuItemLayout itemLayout = (SkuItemLayout) skuContainerLayout.getChildAt(0); // 得到第一个（唯一的一个）规格组
		// 遍历sku列表
		for (int i = 0; i < skuList.size(); i++) { // 遍历数据，获取这个唯一的规格组下的规格
			// 属性值是否可点击flag
			Sku sku = skuList.get(i); // 获取规格的信息的对象（库存、等信息）
			List<SkuAttribute> attributeBeanList = skuList.get(i).getAttributes(); // 获取规格所属的规格组名的列表[{颜色：白色},{尺寸：中}] ，由于是单个规格名，所以是[{颜色：白色}]
			if (sku.getStockQuantity() > 0) { // 得到库存量>0
				String attributeValue = attributeBeanList.get(0).getValue(); // 得到单规格组下---规格item的名称
				itemLayout.optionItemViewEnableStatus(attributeValue); // 设置可点击
			}
		}
	}

	/**
	 * 多个规格组，设置是否点击
	 */
	private void optionLayoutEnableStatusMultipleProperties() {
		for (int i = 0; i < skuContainerLayout.getChildCount(); i++) { // 循环的遍历规格组
			SkuItemLayout itemLayout = (SkuItemLayout) skuContainerLayout.getChildAt(i); // 获取规格组
			// 遍历后台返回的所有的规格的商品的列表
			for (int j = 0; j < skuList.size(); j++) {
				// 属性值是否可点击flag
				boolean flag = false;
				Sku sku = skuList.get(j); // 获取规格的对象
				List<SkuAttribute> attributeBeanList = sku.getAttributes(); // 获取这条信息的，所属【{颜色，红}，{尺寸 ：大 }】 的信息
				// 遍历选中信息列表，selectedAttributeList 中存放了规格组名
				for (int k = 0; k < selectedAttributeList.size(); k++) {
					// i = k，跳过当前属性，避免多次设置是否可点击
					if (i == k) continue;
					// 选中信息为空，则说明未选中，无法判断是否有不可点击的情形，跳过
					if ("".equals(selectedAttributeList.get(k).getValue())) continue;
					// 选中信息列表中不包含当前sku的属性，则sku组合不存在，设置为不可点击
					// 库存为0，设置为不可点击
					if (!selectedAttributeList.get(k).getValue().equals(attributeBeanList.get(k).getValue())
							|| sku.getStockQuantity() == 0) {
						flag = true;
						break;
					}
				}
				// flag 为false时，可点击
				if (!flag) {
					String attributeValue = attributeBeanList.get(i).getValue(); // [{"key":"颜色","value":"粉色" },{"key":"尺码","value":"S" }]
					// 获取 数组中第一个中的规格值
					itemLayout.optionItemViewEnableStatus(attributeValue);

					Log.d("zwk",i+"S号可以点击的颜色有 "+attributeValue);
				}
			}
		}
	}

	/**
	 * 设置所有属性的选中状态
	 */
	private void optionLayoutSelectStatus() {
		for (int i = 0; i < skuContainerLayout.getChildCount(); i++) {
			SkuItemLayout itemLayout = (SkuItemLayout) skuContainerLayout.getChildAt(i);
			itemLayout.optionItemViewSelectStatus(selectedAttributeList.get(i));
		}
	}

	/**
	 * 是否有sku选中
	 *
	 * @return
	 */
	private boolean isSkuSelected() {
		for (SkuAttribute attribute : selectedAttributeList) {
			if (TextUtils.isEmpty(attribute.getValue())) {
				return false;
			}
		}
		return true;
	}

	/**
	 * 获取第一个未选中的属性名
	 *
	 * @return
	 */
	public String getFirstUnelectedAttributeName() {
		for (int i = 0; i < skuContainerLayout.getChildCount(); i++) {
			SkuItemLayout itemLayout = (SkuItemLayout) skuContainerLayout.getChildAt(i);
			if (!itemLayout.isSelected()) {
				return itemLayout.getAttributeName();
			}
		}
		return "";
	}

	/**
	 * 获取选中的Sku
	 *
	 * @return
	 */
	public Sku getSelectedSku() {
		// 判断是否有选中的sku
		if (!isSkuSelected()) {
			return null;
		}
		for (Sku sku : skuList) { // 循环遍历所有的数据
			List<SkuAttribute> attributeList = sku.getAttributes(); // 存放某一条数据里面的他的规格列表
			// 将sku的属性列表与selectedAttributeList匹配，完全匹配则为已选中sku
			boolean flag = true;
			for (int i = 0; i < attributeList.size(); i++) {  // 每一个规格的里面的规格都是两条，所以循环的判断当前选中的规格是否 和后台返回的相同
				if (!isSameSkuAttribute(attributeList.get(i), selectedAttributeList.get(i))) { // 两个数据不相同，flag=false
					flag = false;
				}
			}
			if (flag) {  // 如果两个数据相同，返回true,返回这条数据
				return sku;
			}
		}
		return null;  // 如果没有相同的就返回null
	}

	/**
	 * 点击规格item，更改当前点击的item条件下其他的item的状态值
	 *
	 * @param sku
	 */
	public void setSelectedSku(Sku sku) {
		selectedAttributeList.clear();
		for (SkuAttribute attribute : sku.getAttributes()) {
			selectedAttributeList.add(new SkuAttribute(attribute.getKey(), attribute.getValue()));
		}
		// 清除所有选中状态
		clearAllLayoutStatus();
		// 设置是否可点击
		optionLayoutEnableStatus();
		// 设置选中状态
		optionLayoutSelectStatus();
	}

	/**
	 * 是否为同一个SkuAttribute
	 *
	 * @param previousAttribute
	 * @param nextAttribute
	 * @return
	 */
	private boolean isSameSkuAttribute(SkuAttribute previousAttribute, SkuAttribute nextAttribute) {
		return previousAttribute.getKey().equals(nextAttribute.getKey())
				&& previousAttribute.getValue().equals(nextAttribute.getValue());
	}

	@Override
	public void onSelect(int position, boolean selected, SkuAttribute attribute) {  // 点击规格item的回调
		if (selected) { // 如果是从未选中到选中的状态
			// 选中，保存选中信息
			selectedAttributeList.set(position, attribute);  // 如果position = 0 。则是点击的是颜色规格，position=1 则点击的是尺寸规格
		} else { // 如果是从选中的状态到未选中的状态
			// 取消选中，清空保存的选中信息
			selectedAttributeList.get(position).setValue("");
		}
		clearAllLayoutStatus();
		// 设置是否可点击
		optionLayoutEnableStatus();
		// 设置选中状态
		optionLayoutSelectStatus();
		// 回调接口
		if (isSkuSelected()) {
			listener.onSkuSelected(getSelectedSku());
		} else if (selected) {
			listener.onSelect(attribute);
		} else {
			listener.onUnselected(attribute);
		}
	}
}